package com.yujie.filter;

import com.alibaba.fastjson.JSON;
import com.yujie.dao.MenuDao;
import com.yujie.model.Menu;
import com.yujie.model.dto.SysRoleDTO;
import com.yujie.model.dto.SysUserDTO;
import com.yujie.security.LoginUser;
import com.yujie.utils.ResultJson;
import com.yujie.utils.UserUtil;
import com.yujie.utils.WebUtils;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.regex.Pattern;

/**
 * 动态权限校验
 */
public class AccessDeniedFilter extends OncePerRequestFilter {
    private MenuDao menuDao;

    public AccessDeniedFilter(MenuDao menuDao) {
        this.menuDao = menuDao;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String token = request.getHeader("token");
        if(Objects.isNull(token)){
            filterChain.doFilter(request,response);
            return;
        }
        //获取数据库所有需要权限的菜单
        List<Menu> menuList = menuDao.selectList(null);
        boolean competence=false;
        for (Menu menu : menuList) {
            String menuUrl=menu.getUrl();
            boolean matches = Pattern.matches(menuUrl, request.getServletPath());
            //当前url是否需要权限 true 需要 : false 不需要
            if(matches){
                competence=true;
                break;
            }
        }
        //当前请求不需要权限直接放行
        if(!competence){
            filterChain.doFilter(request,response);
            return;
        }
        //以下是需要权限的处理
        boolean denied=false;
        Set<String> menus =getUserMenus();
        for (String menuUrl : menus) {
            //当前的url和数据库的url匹配
            denied= Pattern.matches(menuUrl,request.getServletPath());
            //true 匹配上 : false 未匹配
            if(denied){
                break;
            }
        }

        if(!denied){
            ResultJson resultJson = new ResultJson(403,"权限不足,无法访问");
            WebUtils.renderString((HttpServletResponse) response, JSON.toJSONString(resultJson));
        }else{
            filterChain.doFilter(request,response);
        }
    }

    /**
     * 获取当前用户的所有权限
     * @return
     */
    private Set<String> getUserMenus(){
        SysUserDTO sysUser = UserUtil.getUser();
        List<SysRoleDTO> roles = sysUser.getRoles();
        Set<String> menus= new HashSet<>();
        for (SysRoleDTO role : roles) {
            List<Menu> menuList = role.getMenuList();
            for (Menu menu : menuList) {
                menus.add(menu.getUrl());
            }
        }
        return menus;
    }
}
